// Grid.h
// Template class which stores objects
// in a 2D grid using a vector base
//
// Nick Kitten
// 2009

#pragma once

#include <vector>
#include <cassert>
using namespace std;

template <class T> 
class Grid
{
private:
	vector<T> grid;
	int _width, _height;

	void resize( int w, int h );

public:
	Grid( int w = 0, int h = 0, const T& value = T() );
	~Grid(){};
	
	typename vector<T>::reference operator()( int i, int j );
	typename vector<T>::const_reference operator()( int i, int j ) const;

	int width() const;
	void width( int );

	int height() const;
	void height( int );

	bool isValid( int i, int j ) const;

	// can add iterator functions for speed boost on vector base

};

template <class T>
Grid<T>::Grid(int w, int h, const T& value )
: _width(w), _height(h)
{
	grid = vector<T>::vector( w * h, value );
}

template <class T>
bool Grid<T>::isValid( int i, int j ) const
{
	return i >= 0 && i < _width && j >= 0 && j < _height;
}

template <class T>
typename vector<T>::reference Grid<T>::operator() ( int i, int j )
{
	assert( isValid( i, j) );
	return this->grid[i + this->_width * j];
}

template <class T>
typename vector<T>::const_reference Grid<T>::operator() ( int i, int j ) const
{
	assert( isValid( i, j) );
	return this->grid[i + this->_width * j];
}

template <class T>
int Grid<T>::width() const
{
	return this->_width;
}

template <class T>
int Grid<T>::height() const
{
	return this->_height;
}

template <class T>
void Grid<T>::resize(int w, int h)
{
	this->_width = w;
	this->_height = h;
	this->grid.resize( w * h );
}

template <class T>
void Grid<T>::width( int w )
{
	this->resize( w, this->_height );
}

template <class T>
void Grid<T>::height( int h )
{
	this->resize( this->_width, h );
}